package com.aries.remoteplus.core;

import java.io.*;
import java.net.*;

import android.os.StrictMode;

public class DiscoverThread extends Thread {
	//
	private static final String TAG = "DiscoverThread";
	private static int BUFFER_LENGTH = 1024;
	public static String MULTICAST_ADDRESS = "230.6.6.6";
	private static final String ID_REQUEST = "RemoteDroid:AnyoneHome";
	private static final String ID_REQUEST_RESPONSE = "RemoteDroid:ImHome";
	
	//
	private int port = 57111;
	private MulticastSocket socket;
	private DatagramSocket inSocket;
	private DiscoverListener listener;
	
	public DiscoverThread(DiscoverListener listener) 
	{
		this.listener = listener;
	}
	
	public DiscoverThread(int port, DiscoverListener listener) 
	{
		this.port = port;
		this.listener = listener;
	}
	
	@Override
	public void run() 
	{
		try 
		{
			this.socket = new MulticastSocket(this.port);
			this.socket.joinGroup(InetAddress.getByName(MULTICAST_ADDRESS));
			this.inSocket = new DatagramSocket(this.port+1);
			this.sendIDRequest();
			this.waitForResponse();
		} catch (IOException e) 
		{
			e.printStackTrace();
		} catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
	}
	
	public void closeSocket() 
	{
		this.socket.close();
		this.inSocket.close();
	}
	
	/**
	 * Send ID Request to multicast group
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void sendIDRequest() throws IOException, InterruptedException 
	{
		byte[] b = ID_REQUEST.getBytes();
		DatagramPacket packet = new DatagramPacket(b, b.length);
		packet.setAddress(InetAddress.getByName(MULTICAST_ADDRESS));
		packet.setPort(this.port);
		StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
		StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(oldPolicy)
								.permitNetwork().build());
		this.socket.send(packet);
		StrictMode.setThreadPolicy(oldPolicy);
		
		Thread.sleep(500);
	}
	
	private void waitForResponse() throws IOException 
	{
		byte[] b = new byte[BUFFER_LENGTH];
		DatagramPacket packet = new DatagramPacket(b, b.length);
		//Log.d(TAG, "Going to wait for packet");
		while (true) 
		{
			this.inSocket.receive(packet);
			this.handleReceivedPacket(packet);
		}
	}
	
	// 
	
	private void handleReceivedPacket(DatagramPacket packet) throws UnsupportedEncodingException 
	{
		String data = new String(packet.getData(), "UTF-8");
		String[] datas  = data.split("[|]");

		if ( datas[0].trim().equals(ID_REQUEST_RESPONSE) ) 
		{
			// We've received a response. Notify the listener
			String serverName = datas[1].trim();
			int udpPort = Integer.parseInt(datas[2].trim());
			this.listener.onAddressReceived(serverName, packet.getAddress().getHostAddress(), udpPort);
		}
	}
	
	//
	
	public static interface DiscoverListener 
	{
		void onAddressReceived(String tServerName, String address, int port);
	}
}
